<html>
<head><meta charset="utf-8"><title>Const string-ish, usable today · t-compiler/const-eval · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/index.html">t-compiler/const-eval</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html">Const string-ish, usable today</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="246393455"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246393455" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Bot+ <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246393455">(Jul 18 2021 at 19:09)</a>:</h4>
<p>For a hacky workaround, this one is surprisingly nice.</p>
<p>Main focuses were const, no macros, and no build​.rs. <del>The unreachable_unchecked is more of a debug aid that can be commented out.</del> Use panic instead.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#![feature(const_panic)]</span><span class="w"></span>

<span class="k">struct</span> <span class="nc">ConString</span><span class="o">&lt;</span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">data</span>: <span class="p">[</span><span class="kt">u8</span><span class="p">;</span><span class="n">N</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="n">len</span>: <span class="kt">u8</span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;</span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="w"> </span><span class="n">ConString</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">const</span><span class="w"> </span><span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">data</span>: <span class="p">[</span><span class="kt">u8</span><span class="p">;</span><span class="n">N</span><span class="p">],</span><span class="w"> </span><span class="n">len</span>: <span class="kt">u8</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">data</span><span class="p">.</span><span class="n">len</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="fm">panic!</span><span class="p">();</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">         </span><span class="bp">Self</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">data</span><span class="p">,</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;</span><span class="k">const</span><span class="w"> </span><span class="n">N</span>: <span class="kt">usize</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Display</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">ConString</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">fmt</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">f</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">std</span>::<span class="n">fmt</span>::<span class="n">Formatter</span><span class="o">&lt;'</span><span class="nb">_</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">std</span>::<span class="n">fmt</span>::<span class="nb">Result</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="bp">self</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">len</span><span class="p">()</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">len</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="o">..</span><span class="p">];</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="c1">// SAFETY: ascii only :)</span>
<span class="w">            </span><span class="n">core</span>::<span class="kt">str</span>::<span class="n">from_utf8_unchecked</span><span class="p">(</span><span class="n">b</span><span class="p">)</span><span class="w"></span>
<span class="w">        </span><span class="p">};</span><span class="w"></span>
<span class="w">        </span><span class="n">f</span><span class="p">.</span><span class="n">write_str</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">type</span> <span class="nc">Constr8</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ConString</span><span class="o">&lt;</span><span class="mi">8</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="k">type</span> <span class="nc">Constr16</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ConString</span><span class="o">&lt;</span><span class="mi">16</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="k">type</span> <span class="nc">Constr32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ConString</span><span class="o">&lt;</span><span class="mi">32</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
<span class="k">type</span> <span class="nc">Constr48</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ConString</span><span class="o">&lt;</span><span class="mi">48</span><span class="o">&gt;</span><span class="p">;</span><span class="w"></span>
</code></pre></div>
<p>Instead of having to return <code>([u8;8], len)</code>, ConString allows to</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">const</span><span class="w"> </span><span class="k">fn</span> <span class="nf">x_to_str</span><span class="p">(</span><span class="n">x</span>: <span class="nc">N</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Constr8</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0_</span><span class="k">u64</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1_</span><span class="k">u32</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="c1">// do some cool bithacks to turn r into ascii</span>
<span class="w">    </span><span class="o">..</span><span class="p">.</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">bytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">r</span><span class="p">.</span><span class="n">to_le_bytes</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="n">Constr8</span>::<span class="n">new</span><span class="p">(</span><span class="n">bytes</span><span class="p">,</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="246403992"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246403992" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matt1992 <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246403992">(Jul 18 2021 at 23:13)</a>:</h4>
<p>That use of <code>core::hint::unreachable_unchecked</code> is unsound, this non-<code>unsafe</code> function can be called at runtime, and then cause Undefined Behavior.</p>



<a name="246404112"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246404112" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246404112">(Jul 18 2021 at 23:16)</a>:</h4>
<p>also why do you need the <code>core_intrinsics</code> feature?</p>



<a name="246404113"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246404113" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246404113">(Jul 18 2021 at 23:16)</a>:</h4>
<p>but this looks neat :)</p>



<a name="246409061"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246409061" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246409061">(Jul 19 2021 at 01:37)</a>:</h4>
<blockquote>
<p>That use of <code>core::hint::unreachable_unchecked</code> is unsound, this non-<code>unsafe</code> function can be called at runtime, and then cause Undefined Behavior.</p>
</blockquote>
<p>Even if called in const, it can still cause Undefined Behaviour.</p>



<a name="246411718"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246411718" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246411718">(Jul 19 2021 at 02:56)</a>:</h4>
<p>While technically true, I'm fairly certain any const call to that method is caught in const eval.</p>



<a name="246426739"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246426739" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246426739">(Jul 19 2021 at 08:05)</a>:</h4>
<p><span class="user-mention silent" data-user-id="245610">Jacob Pratt</span> <a href="#narrow/stream/146212-t-compiler.2Fconst-eval/topic/Const.20string-ish.2C.20usable.20today/near/246411718">said</a>:</p>
<blockquote>
<p>While technically true, I'm fairly certain any const call to that method is caught in const eval.</p>
</blockquote>
<p>that alone is not enough -- we could also do optimizations that exploit <code>unreachable_unchecked</code>; if we did, then catching the calls during evaluation does not help. we currently dont do such optimizations but there is no guarantee for this.</p>



<a name="246436080"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246436080" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246436080">(Jul 19 2021 at 09:58)</a>:</h4>
<p>Doesn't <a href="https://rust-lang.github.io/rfcs/3016-const-ub.html">RFC 3016</a> specify that this is caught reliably?</p>



<a name="246436147"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246436147" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246436147">(Jul 19 2021 at 09:59)</a>:</h4>
<p>I wanted it to say that, but the RFC was weakened to not guarantee anthing</p>



<a name="246436150"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246436150" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246436150">(Jul 19 2021 at 09:59)</a>:</h4>
<p>From the RFC:</p>
<blockquote>
<p>For <code>rustc</code> specifically at the time the RFC is written, a lot of UB will actually be detected reliably:</p>
</blockquote>
<p>and</p>
<blockquote>
<p>However, this is just a snapshot of what <code>rustc</code> currently does. None of this is _guaranteed_, and <code>rustc</code> may relax or otherwise change its UB checking any time.</p>
</blockquote>



<a name="246623017"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246623017" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Bot+ <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246623017">(Jul 20 2021 at 17:27)</a>:</h4>
<p>To be honest I originally had unreachable! there, but had to swap it to its unsafe counterpart because the former isn't const yet.</p>
<p>Yes, at best it is an awful footgun but it does its job for now.</p>
<p>In practice this instance of UB crashes my non-const test suite with illegal instruction, so only damage is loss of a nice backtrace. With extensive tracing/logging the backtrace is actually redundant.</p>



<a name="246623722"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246623722" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Bot+ <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246623722">(Jul 20 2021 at 17:33)</a>:</h4>
<p>So turns out my abuse of UB was entirely pointless.</p>
<p>I did spot <a href="https://github.com/rust-lang/rust/pull/86998">#​86998</a> earlier but I was unaware plain <code>panic!();</code> already works with <code>#![feature(const_panic)]</code>.</p>



<a name="246624494"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/146212-t-compiler/const-eval/topic/Const%20string-ish%2C%20usable%20today/near/246624494" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/146212-t-compiler/const-eval/topic/Const.20string-ish.2C.20usable.20today.html#246624494">(Jul 20 2021 at 17:38)</a>:</h4>
<blockquote>
<p>In practice this instance of UB crashes my non-const test suite with illegal instruction,</p>
</blockquote>
<p>You might already know this, but the result might be very different when the code is called in a different context. UB is "non-local" in its effect; just because your code causes SIGILL here doesn't mean it'll do the same for other callers / compiler versions / compiler settings.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>